package com.sp.synchronized_;

/**
 * 模拟线程死锁
 *
 * 释放锁的条件:
 * 1. 当前线程的同步方法, 同步代码块结束
 * 2. 当前线程在同步代码块, 同步方法中遇到break, return
 * 3. 当前线程在同步代码块, 同步方法中出现了未处理的Error或Exception, 导致异常结束
 * 4. 当前线程在同步代码块, 同步方法中执行了线程对象的wait()方法, 单线成成在听, 并释放锁
 *
 * 下面的操作不会释放锁:
 * 1. 线程执行同步代码块或同步方法时, 程序调用Thread.sleep(), Thread.yield()方法暂停当前线程的执行, 不会释放锁
 * 2. 线程执行同步代码块时, 其他线程调用了该线程的suspend()方法将该线程挂起, 该线程不会释放锁
 */
public class DeadLock_ {
    public static void main(String[] args) {
        DeadLockDemo A = new DeadLockDemo(true);
        A.setName("A线程");
        DeadLockDemo B = new DeadLockDemo(false);
        B.setName("B线程");
        A.start();
        B.start();

    }
}


class DeadLockDemo extends Thread {
    static Object o1 = new Object();//保证多线程, 共享一个对象, 这里使用static
    static Object o2 = new Object();
    boolean flag;

    public DeadLockDemo (boolean flag) {
        this.flag = flag;
    }

    @Override
    public void run() {
        if (flag) {
            synchronized (o1) {
                System.out.println(Thread.currentThread().getName() + " 进入1");
                synchronized (o2) {
                    System.out.println(Thread.currentThread().getName() + " 进入2");
                }
            }
        } else {
            synchronized (o2) {
                System.out.println(Thread.currentThread().getName() + " 进入3");
                synchronized (o1) {
                    System.out.println(Thread.currentThread().getName() + " 进入4");
                }
            }
        }
    }
}